package socket;

import com.jfinal.plugin.activerecord.Db;
import demo.JfinalConfig;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketAddress;
import java.text.SimpleDateFormat;
import java.util.Date;

public class TcpCardSimpleServer {

    //Size of receive buffer
    private static final int BUFSIZE = 9999;

    public static final int port = 6200;

    /**
     * @param args
     */
    public static void main(String[] args) {
        //Test for correct # of args
/*        if (args.length != 1) {
            throw new IllegalArgumentException("Parameter(s):<Port>");
        }*/
        int servPort = args.length > 0 ? Integer.parseInt(args[0]) : port;

        //Create a server socket to accept client connection request
        ServerSocket servSocket = null;
        int recvMsgSize = 0;

        try {
            test1(servPort);
//            test2(servPort);
        } catch (Exception e) {
            e.printStackTrace();
        }


    }

    private static void test2(int servPort) {
        try {
            //1.建立一个服务器Socket(ServerSocket)绑定指定端口
            ServerSocket serverSocket = new ServerSocket(servPort);
            while (true) {
                //2.使用accept()方法阻止等待监听，获得新连接
                Socket socket = serverSocket.accept();
                //3.获得输入流
                InputStream is = socket.getInputStream();
                BufferedReader br = new BufferedReader(new InputStreamReader(is));
                //获得输出流
                OutputStream os = socket.getOutputStream();
                PrintWriter pw = new PrintWriter(os);
                //4.读取用户输入信息
                String info = null;
                String receiveData = null;
                while (!((info = br.readLine()) == null)) {
                    System.out.println("########## input:" + info);
                    receiveData += info;
                }
                //给客户一个响应
                String reply = "00101000011";
//                String reply = handResult(receiveData);
                pw.write(reply);
                pw.flush();
                System.out.println("########## output:" + reply);
                //5.关闭资源
                pw.close();
                os.close();
                br.close();
                is.close();
                socket.close();

            }
        } catch (IOException e) {
            e.printStackTrace();
//            serverSocket.close();
        }
    }

    private static void test1(int servPort) throws IOException {
        ServerSocket servSocket;
        int recvMsgSize;
        byte[] receivBuf = new byte[BUFSIZE];
        servSocket = new ServerSocket(servPort);
        while (true) {
            Socket clientSocket = servSocket.accept();
            SocketAddress clientAddress = clientSocket.getRemoteSocketAddress();
//            System.out.println("Handling client at " + clientAddress);

            InputStream in = clientSocket.getInputStream();
            OutputStream out = clientSocket.getOutputStream();

            String receivedData = null;
            //receive until client close connection,indicate by -l return
/*            while ((recvMsgSize = in.read(receivBuf)) != -1) {
                receivedData = new String(receivBuf, "utf-8").trim();

                System.out.println("###receivedData:" + receivedData);
                //out.write(receivBuf, 0, recvMsgSize);
                //调用相应方法处理
                handResult(receivedData);
            }*/

            in.read(receivBuf);
            receivedData = new String(receivBuf, "utf-8").trim();

            System.out.println("###receivedData:" + receivedData);

            String rs = handResult(receivedData);
//
//            System.out.println("###send:" + rs);
            out.write((rs).getBytes());
            /*int i = saveToClockRecord(receivedData);
            out.write(("return_flag: " + i).getBytes());*/

            clientSocket.close();
        }
    }


    private static String handResult(String str) {
        String rs = "";
        if (str.length() < 10) {
            return rs;
        }
        // 第1-9为设备号，第10-21为时间（161115204911） 第22-31位为10位卡号
        String op = str.substring(21, 31);
        switch (op) {
            case "0000000000"://心跳包 #ACK 2015-05-09 08:14:08
                String d = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
                rs = "#ACK " + d;
                break;
            default:
                System.out.println("###op:" + op);
        }
        return rs;
    }

    private static void parseData(String str) {
        /**
         * example
         * 0055340340269032000005      01000003e9  201611071747441
         * 结构：（4位包长度 + 2位操作码 + 4位序列号 + 18位设备终端ID） + （2位卡数量 + 10位卡号） + （14位日期 + 0或1打卡进校离校字段）
         */
        String deviceId = str.substring(10, 28).trim();

        String cardNum = str.substring(28, 30).trim();
        int n = Integer.parseInt(cardNum, 16);

        for (int i = 0; i < n; i++) {//每次有效信息长度为25位
            String s = str.substring(30 + 25 * i, 55 + 25 * i).trim();
            String card = s.substring(0, 10).trim();
            String date = s.substring(10, 24).trim();
            String type = s.substring(24, 25);

            card = String.valueOf(Integer.parseInt(card, 16));

            saveData(deviceId, card, date, Integer.parseInt(type));
        }
    }

    private static int saveData(String deviceId, String card, String dateStr, int type) {
        JfinalConfig.start();
        String sql = "INSERT INTO clock_record (id, device_id, card_id, type, start_time)" +
                " VALUES (nextval('clock_sequence'), ?, ?, ?, to_timestamp(?, 'yyyyMMddhh24miss'));";
        int i = 0;
        try {
//            Date date = new SimpleDateFormat("yyyyMMddHHmmss").parse(dateStr);
            i = Db.update(sql, deviceId, card, type, dateStr);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return i;
    }


}